import * as fs from 'fs'
import * as path from 'path'
import i18n from '@/i18n'
import { Assist } from '../assist/assist'
import { md5 } from '../common'
import { AppLogger } from '../logger/app-logger'

export class FileUtil {
  /**
   * 图片base64正则
   */
  static readonly IMAGE_BASE64_REG = /^data:([A-Za-z-+\/]+);base64,(.+)$/i

  /**
   * 保存文件
   * @param filePath 存储路径
   * @param file 文件
   */
  static async saveFile(filePath: string, file: Express.Multer.File) {
    return this.saveChunkFile(filePath, file.buffer)
  }

  /**
   * 保存二进制文件
   * @param filePath 存储路径
   * @param binary 文件内容
   */
  static async saveBinaryFile(filePath: string, binary: string | Buffer) {
    return this.saveChunkFile(filePath, binary, 'binary')
  }

  /**
   * 保存文件
   * @param filePath
   * @param chunk
   * @param encoding
   * @returns
   */
  static async saveChunkFile(filePath: string, chunk: any, encoding?: BufferEncoding) {
    const absolutePath = path.isAbsolute(filePath) ? filePath : path.join(__dirname, filePath)
    const dir = path.dirname(absolutePath)

    if (!fs.existsSync(dir)) {
      fs.mkdirSync(dir, { recursive: true })
    }

    let ws: fs.WriteStream | null = null

    return await new Promise<void>((resolve, reject) => {
      ws = fs.createWriteStream(absolutePath)

      ws.write(chunk, encoding, err => {
        if (err) {
          AppLogger.error(FileUtil.name, () => i18n.t('lhy-common.os.file-util.12154284-0') + JSON.stringify(err))
          reject(err)
        } else {
          AppLogger.info(FileUtil.name, () => i18n.t('lhy-common.os.file-util.12154284-1') + absolutePath)
          resolve()
        }
      })
    }).finally(() => {
      ws?.close()
    })
  }

  /**
   * 读取文件内容md5
   * @param file 文件
   * @returns
   */
  static getFileMd5(file: Express.Multer.File | Buffer) {
    return md5((file as Express.Multer.File).buffer || (file as Buffer))
  }

  /**
   * 读取文件的后缀
   * @param file 文件
   * @returns
   */
  static getFileExt(file: Express.Multer.File) {
    return path.extname(file.originalname).slice(1).replace(/\?.*$/, '')
  }

  /**
   * 读取地址的后缀
   * @param url
   * @returns
   */
  static getUrlExt(url: string) {
    return path.extname(url).slice(1).replace(/\?.*$/, '')
  }

  /**
   * 读取url中的名称
   * @param url
   * @returns
   */
  static getUrlName(url: string) {
    return path.basename(url)
  }

  /**
   * 从base64图片中得出相关信息
   * @param base64
   * @returns
   */
  static getBase64ImageInfo(base64: string) {
    const matches = base64.match(this.IMAGE_BASE64_REG) || []

    Assist.threw(matches.length !== 3, i18n.t('lhy-common.os.file-util.12154284-2'))

    const content = Buffer.from(matches[2], 'base64')

    return {
      ext: matches[1],
      name: `${this.getFileMd5(content)}.${matches[1]}`,
      content,
    }
  }
}
